#!/usr/bin/env python3
#
# Script to generate the map for libstdc++ std::chrono::current_zone under Windows.
#
# This file is part of GCC.
#
# GCC is free software; you can redistribute it and/or modify it under
# the terms of the GNU General Public License as published by the Free
# Software Foundation; either version 3, or (at your option) any later
# version.
#
# GCC is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
# for more details.
#
# You should have received a copy of the GNU General Public License
# along with GCC; see the file COPYING3.  If not see
# <http://www.gnu.org/licenses/>.

# To update the Libstdc++ static data in src/c++20/windows_zones-map.h download the latest:
# https://raw.githubusercontent.com/unicode-org/cldr/master/common/supplemental/windowsZones.xml
# Then run this script and save the output to
# src/c++20/windows_zones-map.h

import os
import sys
import xml.etree.ElementTree as et

if len(sys.argv) != 2:
    print("Usage: %s <windows zones xml>" % sys.argv[0], file=sys.stderr)
    sys.exit(1)

self = os.path.basename(__file__)
print("// Generated by scripts/{}, do not edit.".format(self))
print("""
// Copyright The GNU Toolchain Authors.
//
// This file is part of the GNU ISO C++ Library.  This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.

// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.

// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.

// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
// <http://www.gnu.org/licenses/>.

""")

class WindowsZoneMapEntry:
    def __init__(self, windows, territory, iana):
        self.windows = windows
        self.territory = territory
        self.iana = iana

    def __lt__(self, other):
        return (self.windows, self.territory) < (other.windows, other.territory)

windows_zone_map = []

tree = et.parse(sys.argv[1])
xml_zone_map = tree.getroot().find("windowsZones").find("mapTimezones")

for entry in xml_zone_map.iter("mapZone"):
    iana = entry.attrib["type"]
    space = iana.find(" ")
    if space != -1:
        iana = iana[0:space]
    windows_zone_map.append(WindowsZoneMapEntry(entry.attrib["other"], entry.attrib["territory"], iana))

# Sort so we can use binary search on the array.
windows_zone_map.sort()

# Skip territories which have the same IANA zone as 001, so we can reduce the data.
last_windows_zone = ""
for entry in windows_zone_map[:]:
    if entry.windows != last_windows_zone:
        if entry.territory != "001":
            raise ValueError('Territory "001" not the first one, this breaks assumptions in tzdb.cc!')
        last_windows_zone = entry.windows
        fallback_iana = entry.iana
    else:
        if entry.iana == fallback_iana:
            windows_zone_map.remove(entry)

print("""struct windows_zone_map_entry
{{
  wstring_view windows_name;
  wstring_view territory;
  string_view iana_name;
}};

static constexpr array<windows_zone_map_entry, {}> windows_zone_map{{
  {{""".format(len(windows_zone_map)))

for entry in windows_zone_map:
    print('    {{L"{}", L"{}", "{}"}},'.format(entry.windows, entry.territory, entry.iana))

print("""  }
};""")

# src/c++20/tzdb.cc gives an error if this macro is not defined.
# Do this last, so that the generated output is not usable unless we reach here.
print("\n#define _GLIBCXX_WINDOWS_ZONES_MAP_COMPLETE")
